package com.controler;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;

import com.annotation.ControlerInfo;
import com.bean.RegistAnnotationBean;

import com.action.ActionForm;

public class ActionServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;

	@Override
	public void doGet(HttpServletRequest request,HttpServletResponse response)
	throws IOException,ServletException
	{
		
		String url = request.getRequestURI();
		System.out.println(url);
		
		//主要用于反射 内容信息
		String[] anctionPath = url.split("/");
		String action = anctionPath[anctionPath.length - 1];
		ServletContext scontext = request.getServletContext();
		Map<String, RegistAnnotationBean> loginMap = (Map<String, RegistAnnotationBean>)scontext.getAttribute("RegistAnnotation");
		RegistAnnotationBean lb = loginMap.get("/" + action);
		if(lb == null){
			return;
		}
		String userBeanName = lb.getFormValue();
		
		if(userBeanName != null && !"".equals(userBeanName)){
			try{
				ActionForm af = getFull(userBeanName, request, lb);
				Method me = lb.getMethodMap().get("excute");
				Class<?> cl11 = Class.forName("com.annotation.RegistMyPage");
				String pathkk = (String) me.invoke(cl11.newInstance(), af, lb.getSuccessPath(), lb.getFailPath());
				request.getRequestDispatcher(pathkk).forward(request, response);
			}catch(Exception e){
				e.printStackTrace();
			}
		}
	}
	
	@Override
	public void doPost(HttpServletRequest request,HttpServletResponse response)
	throws IOException,ServletException
	{
		this.doGet(request, response);
	}
	
	public String getPath(String servletpath)
	{
		return servletpath.split("\\.")[0];
	}
	
	public static ActionForm getFull(String userBeanName, HttpServletRequest req,  RegistAnnotationBean lb){
		ActionForm af = null;
		try{
			Class<?> userBeanClass = Class.forName(userBeanName);
			af = (ActionForm)userBeanClass.newInstance();
			Field[] fields = userBeanClass.getDeclaredFields();
			for(Field field : fields){
				field.setAccessible(true);
				field.set(af, req.getParameter(field.getName()));
				field.setAccessible(false);
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		return af;
	}
	
	@Override
	public void init(ServletConfig config) throws ServletException {
		// 存储路径内容
		Map<String, RegistAnnotationBean> loginMap = new HashMap<>();
		// Action内容
		Map<String, ActionForm> actionFormMap = new HashMap<>();

		ServletContext applition = config.getServletContext();
		// 获取Annotation 路径
		String initPath = config.getInitParameter("contextConfigLocation");
		// 绝对路径
		String abPath = applition.getRealPath(initPath);
		System.out.println("绝对路径" + abPath);
		// 获取全路径
		String allPath = applition.getRealPath("WEB-INF\\classes");

		SAXBuilder sb = new SAXBuilder();
		try {
			Document document = sb.build(new File(abPath));
			Element element = document.getRootElement();
			// 获取子节点 父节点是<xml-body>
			Element elementChild = element.getChild("baseAnnotation");
			String path = elementChild.getAttributeValue("path");
			System.out.println(path);
			// 判断是不是整体包还是单个文件 截取一下文件路径
			int indexMuti = path.indexOf("*");
			// 替换后标点符号内容
			String newPath = path.substring(0, indexMuti - 1).replaceAll("\\.","\\\\");
			// 获取挡圈包内容信息
			System.out.println(newPath);
			// 新路径拼接
			String temp = allPath + File.separator + newPath;
			File file = new File(temp);
			// 循环遍历文件
			loopFile(file, loginMap);
			applition.setAttribute("RegistAnnotation", loginMap);
			applition.setAttribute("RegistAnnotationForm", actionFormMap);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		/*
		 * File file = new File(path); loopFile(file);
		 */
	}
	
	/**
	 * 循环读取文件
	 * 
	 * @param path
	 */
	public void loopFile(File file, Map<String, RegistAnnotationBean> loginMap) {
		// 判断是否是文件夹
		if (file.isDirectory()) {
			File[] files = file.listFiles();
			for (File f : files) {
				loopFile(f, loginMap);
			}
		} else {
			// 执行内容信息
			annotionInfoMation(file, loginMap);
		}
	}

	/**
	 * 读取类中的内容
	 */
	public void annotionInfoMation(File file, Map<String, RegistAnnotationBean> loginMap) {
		//创建一个新的RegistAnnotationBean内容
		RegistAnnotationBean lab = new RegistAnnotationBean();
		Map<String, Method> annotationMethod = new HashMap<>();
		lab.setMethodMap(annotationMethod);
		
		String abFilePath = file.getPath();
		// 获取所以位置
		int backageIndex = abFilePath.indexOf("WEB-INF\\classes") + 16;
		String temp = abFilePath.substring(backageIndex);
		String str = temp.substring(0, temp.indexOf(".class"));
		String className = str.replaceAll("\\\\", "\\.");
		System.out.println("类名称 ：" + className);
		// 获取类 反射获取内容
		try {
			Class<?> x = Class.forName(className);
			// 查找注解内容 有类解释 有方法解释@
			Method[] methods = x.getMethods();
			if (methods != null) {
				for (Method method : methods) {
					ControlerInfo li = method.getAnnotation(ControlerInfo.class);
					if (li == null) {
						continue;
					}
					String path = li.path();
					String formValue = li.formValue();
					String successPath = li.successPath();
					String failPath = li.failPath();
					lab.setFormValue(formValue);
					lab.setPath(path);
					lab.setFailPath(failPath);
					lab.setSuccessPath(successPath);
					System.out.println(method.getName());
					annotationMethod.put(method.getName(), method);
					loginMap.put(path, lab);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
}
